﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTunesFastForward.Forms;
using iTunesFastForward.LastFM;
using iTunesFastForward.Lyrics;
using iTunesFastForward.LyricsWikiSOAP;
using System.Net.NetworkInformation;
using System.Net;
using iTunesFastForward.Genpuid;
using System.Reflection;

namespace iTunesFastForward
{
    public partial class iTunesFastForwardForm : Form
    {

        private class ShortcutElements
        {
            public int TempValue { get; set; }
            public Keys TempModifiers { get; set; }
            public Keys TempKeys { get; set; }

            public Shortcut Shortcut { get; set; }
            public TextBox Textbox { get; set; }
            public Button ValidationButton { get; set; }
            public Button UnregisterButton { get; set; }
            public CheckBox WinCheckBox { get; set; }
        }

        private class LyricsDownloadAndApplyArgs
        {
            public iTunesLib.IITTrack Track { get; set; }
            public bool Force { get; set; }
        }

        internal class LoadingStatusChangedEventArgs : EventArgs
        {
            public string StatusText { get; set; }
        }
        internal delegate void LoadingStatusChangedEventHandler(object sender, LoadingStatusChangedEventArgs e);

        private string _tempCoverFileName;
        ToastForm _toastForm;
        ShortcutsManager _scManager;
        LastFMManager _lastfm;
        LyricsManager _lyrics;
        const int coversPerPage = 6;
        int _coversNumPage = 0;
        List<AlbumCover> _covers;
        Dictionary<string, ShortcutElements> _shortcuts;
        LoadingForm _loadingForm;
        private delegate void EmptyDelegate();
        LyricsForm _lyricsForm;

        public ITTrackInfos[] MusicDNSInfos { get; set; }

        internal event LoadingStatusChangedEventHandler LoadingStatusChanged;

        public iTunesFastForwardForm()
        {
            InitializeComponent();
        }

        private void Initialize()
        {
            //OnLoadingStatusChanged("Checking connection state...");
            //Utils.CheckInternetConnection(pingSender_PingCompleted);

            OnLoadingStatusChanged("Starting iTunes...");
            iTunesActions action = iTunesActions.Instance;

            OnLoadingStatusChanged("Initializing shortcuts...");
            InitializeShortcutsTab();

            OnLoadingStatusChanged("Initializing covers...");
            InitializeCoversTab();

            OnLoadingStatusChanged("Initializing toaster...");
            InitializeToasterTab();

            OnLoadingStatusChanged("Initializing lastfm...");
            InitializeLastFMTab();

            OnLoadingStatusChanged("Initializing lyrics...");
            InitializeLyricsTab();

            InitializeAbout();

            iTunesActions.Instance.TrackPlayedOrChanged += new iTunesActions.TrackEventHandler(Instance_TrackPlayed);
            iTunesActions.Instance.COMCallStateChanged += new iTunesActions.COMCallStateEventHandler(Instance_COMCallStateChanged);

            iTFFTabControl.SelectedTab = aboutTabPage;

            lastfmTimer.Enabled = true;
            checkInternetConnectionTimer.Enabled = true;

            WindowState = FormWindowState.Normal;
            FormHide();
        }


        #region Form show/hide load/leave management
        private void iTunesFastForwardForm_Load(object sender, EventArgs e)
        {
            loadingBackgroundWorker.RunWorkerAsync();
        }

        private void loadingBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            _loadingForm = new LoadingForm(this);
            this.Invoke(new EmptyDelegate(_loadingForm.Show));
            this.Invoke(new EmptyDelegate(Initialize));
            this.Invoke(new EmptyDelegate(_loadingForm.Close));
        }

        private void iTunesFastForwardForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                FormHide();
            }

            else
            {
                iTFFSettings.Instance.Save();
                iTunesActions.Instance.Dispose();
                if (_tempCoverFileName != null)
                {
                    try
                    {
                        File.Delete(_tempCoverFileName);
                    }
                    catch (Exception)
                    {
                    }
                }
            }
        }

        private void FormHide()
        {
            this.WindowState = FormWindowState.Minimized;
            this.Visible = false;
        }

        private void FormShow()
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
            this.BringToFront();
        }
        #endregion

        private void iTFFTabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (iTFFTabControl.SelectedTab.Name == "coversTabPage")
                CoversSetPlayingTrack();
        }

        void OnLoadingStatusChanged(string statusText)
        {
            if (LoadingStatusChanged != null)
                LoadingStatusChanged(this, new LoadingStatusChangedEventArgs { StatusText = statusText });
        }
        private delegate void TrackCommandDelegate(iTunesLib.IITTrack iITTrack);
        private delegate void ShowToastDelegate(iTunesLib.IITTrack iITTrack, bool force);

        void Instance_TrackPlayed(object sender, TrackEventArgs e)
        {
            // on invoke parce que sinon ca marche pas

            // le notifyicon text
            this.Invoke(new TrackCommandDelegate(ChangeNotifyIconText), e.Track);

            // le toast
            this.Invoke(new ShowToastDelegate(ShowToast), e.Track, false);

            // le lastfm
            this.Invoke(new TrackCommandDelegate(LastFMBeginPlay), e.Track);

            // les lyrics
            this.Invoke(new TrackCommandDelegate(LyricsPlay), e.Track);
        }


        void Instance_COMCallStateChanged(object sender, COMCallStateEventArgs e)
        {
            // on invoke parce que sinon ca marche pas

            if (e.Disabled)
            {
                iTFFNotifyIcon.BalloonTipTitle = "iTunes's busy";
                iTFFNotifyIcon.BalloonTipText = "Connection with iTunes lost. The application might not work anymore until connection is restored.";
                iTFFNotifyIcon.BalloonTipIcon = ToolTipIcon.Warning;
            }
            else
            {
                iTFFNotifyIcon.BalloonTipTitle = "iTunes's back";
                iTFFNotifyIcon.BalloonTipText = "Connection with iTunes restored.";
                iTFFNotifyIcon.BalloonTipIcon = ToolTipIcon.Info;
            }

            iTFFNotifyIcon.ShowBalloonTip(3000);
        }

        public Image GetArtworkAsImage(iTunesLib.IITTrack track)
        {
            if (_tempCoverFileName == null)
                _tempCoverFileName = Path.GetTempFileName();

            try
            {
                track.Artwork[1].SaveArtworkToFile(_tempCoverFileName);
                Image ret;
                using (FileStream fs = File.OpenRead(_tempCoverFileName))
                {
                    ret = Image.FromStream(fs);
                }
                File.Delete(_tempCoverFileName);
                return ret;
            }
            catch (Exception)
            {
                return null;
            }


        }

        //private PingCompletedEventHandler _pingCompletedHandler;
        //private void checkInternetConnectionTimer_Tick(object sender, EventArgs e)
        //{
        //    if (!Utils.IsConnectedToInternet)
        //    {
        //        if (_pingCompletedHandler == null)
        //            _pingCompletedHandler = new PingCompletedEventHandler(pingSender_PingCompleted);
        //        Utils.CheckInternetConnection(_pingCompletedHandler);
        //    }
        //}

        private void pingSender_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            if (!e.Cancelled && e.Error == null)
            {
                if (_lastfm != null && !_lastfm.HandShaked)
                    LastFMTryHandshake();
            }
            else if (_lastfm != null)
                _lastfm.HandShaked = false;
        }


        #region Notify icon
        private void iTFFNotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            FormShow();
        }

        private void showshortkeysToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormShow();
            scTabPage.Show();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_shortcuts != null)
                _scManager.DisposeShortcuts(_shortcuts.Select(s => s.Value).Select(s => s.Shortcut).ToArray());
            Application.Exit();
        }

        private void convertplaylistsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!iTunesActions.Instance.COMCallDisabled)
            {
                new iTunesPCForm().Show();
            }
        }

        private void getAlbumCoverToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormShow();
            coversTabPage.Show();
        }

        private void configurationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormShow();
            aboutTabPage.Show();
        }

        private void downloadTagsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MusicDNSSearchTagsForSelectedTrack();
        }

        private void ChangeNotifyIconText(iTunesLib.IITTrack iITTrack)
        {
            string text = string.Format("iTFF\n{0}\n{1}\n{2}", iITTrack.Name, iITTrack.Artist, iITTrack.Album);
            if (text.Length > 63)
                text = text.Substring(0, 63);
            iTFFNotifyIcon.Text = text;
        }
        #endregion

        #region Shortcuts
        private void InitializeShortcutsTab()
        {
            _scManager = new ShortcutsManager(this);

            // récupérer les raccourcis et les afficher
            var scs = _scManager.GetAllShortcuts();
            _shortcuts = new Dictionary<string, ShortcutElements>();

            foreach (var sc in scs)
                _shortcuts.Add(sc.Key, new ShortcutElements { Shortcut = sc.Value });

            scTableLayoutPanel.Visible = false;

            scTableLayoutPanel.SuspendLayout();

            // changer la taille du layout
            scTableLayoutPanel.Controls.Clear();
            scTableLayoutPanel.RowCount = _shortcuts.Keys.Count;
            //foreach (TableLayoutStyle item in scTableLayoutPanel.RowStyles)
            //    item.SizeType = SizeType.AutoSize;


            int row = 0;
            foreach (var scel in _shortcuts.Values)
            {
                var sc = scel.Shortcut;
                // créer les controles
                if (sc.HasSeparatorBefore)
                {
                    scTableLayoutPanel.RowStyles[row] = new RowStyle(SizeType.Absolute, 20);
                    row++;
                }

                // le label avec le nom
                Label l = new Label();
                l.Text = sc.Representation;
                l.Anchor = AnchorStyles.Left;
                l.Font = new Font(this.Font, FontStyle.Bold);
                l.AutoSize = true;

                // la textbox
                TextBox t = new TextBox();
                t.Text = sc.Keys.ToString();
                toolTip.SetToolTip(t, sc.Keys.ToString());
                t.Size = new Size(150, 20);
                t.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
                t.KeyDown += new KeyEventHandler(Textboxes_KeyDown);
                t.AccessibleName = sc.Name;

                // le bouton de validation
                Button v = new Button();
                v.Size = new Size(28, 22);
                v.AccessibleName = sc.Name;
                toolTip.SetToolTip(v, "Validate and apply");
                v.ImageList = imageList;
                v.ImageIndex = 0;
                v.Click += new EventHandler(Validate_Click);

                // le bouton d'annulation
                Button u = new Button();
                u.Size = new Size(28, 22);
                toolTip.SetToolTip(u, "Unregister shortcut");
                u.AccessibleName = sc.Name;
                u.ImageList = imageList;
                u.ImageIndex = 1;
                u.Click += new EventHandler(Unregister_Click);

                // le checkbox touche win
                CheckBox c = new CheckBox();
                c.Anchor = AnchorStyles.None;
                c.Text = "Win";
                c.AutoSize = true;
                c.AccessibleName = sc.Name;
                c.Checked = (sc.Modifiers | Keys.LWin) == sc.Modifiers;
                c.CheckedChanged += new EventHandler(Win_CheckedChanged);

                scel.Textbox = t;
                scel.UnregisterButton = u;
                scel.ValidationButton = v;
                scel.WinCheckBox = c;

                // on met tout ca dans le layout panel
                scTableLayoutPanel.Controls.Add(l, 0, row);
                scTableLayoutPanel.Controls.Add(t, 1, row);
                scTableLayoutPanel.Controls.Add(c, 2, row);
                scTableLayoutPanel.Controls.Add(v, 3, row);
                scTableLayoutPanel.Controls.Add(u, 4, row);

                row++;

                _scManager.RegisterShortcut(sc, t.Handle);
            }

            scTableLayoutPanel.ResumeLayout();
            scTableLayoutPanel.Visible = true;
        }

        void Win_CheckedChanged(object sender, EventArgs e)
        {
            if (((CheckBox)sender).Checked)
                _shortcuts[((Control)sender).AccessibleName].TempModifiers = _shortcuts[((Control)sender).AccessibleName].TempModifiers | Keys.LWin;
            else
                _shortcuts[((Control)sender).AccessibleName].TempModifiers = _shortcuts[((Control)sender).AccessibleName].TempModifiers ^ Keys.LWin;
        }

        void Unregister_Click(object sender, EventArgs e)
        {
            Shortcut sc = _shortcuts[((Control)sender).AccessibleName].Shortcut;

            _scManager.UnsetShortcut(sc);
            _shortcuts[((Control)sender).AccessibleName].Textbox.Text = Keys.None.ToString();
        }

        void Validate_Click(object sender, EventArgs e)
        {
            Shortcut sc = _shortcuts[((Control)sender).AccessibleName].Shortcut;
            try
            {
                _scManager.UnsetShortcut(sc);
                sc.Keys = _shortcuts[((Control)sender).AccessibleName].TempKeys;
                sc.Modifiers = _shortcuts[((Control)sender).AccessibleName].TempModifiers;
                sc.Value = _shortcuts[((Control)sender).AccessibleName].TempValue;
                _scManager.SetShortcut(sc, _shortcuts[((Control)sender).AccessibleName].Textbox.Handle);
            }
            catch (ApplicationException ae)
            {
                Utils.ShowErrorMessage(string.Format("Unable to apply this shortcut. It's maybee already used.\n Error: {0}", ae.Message), "Error");
            }
        }

        void Textboxes_KeyDown(object sender, KeyEventArgs e)
        {
            TextBox tb = (TextBox)sender;
            tb.Text = e.KeyData.ToString();

            ShortcutElements sc = _shortcuts[tb.AccessibleName];
            sc.TempModifiers = e.Modifiers;
            sc.TempKeys = e.KeyData;
            sc.TempValue = e.KeyValue;

            toolTip.SetToolTip(_shortcuts[tb.AccessibleName].Textbox, e.KeyData.ToString());

            e.Handled = true;
            e.SuppressKeyPress = true;

        }
        #endregion

        #region Covers
        private void InitializeCoversTab()
        {
            // covers
            coversStoreMinimizedImageCheckBox.Checked = iTFFSettings.Instance.CoversStoreMinimizedImage;
            coversStoreMinimizedImageCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "CoversStoreMinimizedImage");

            coversApplyAlbumCheckBox.Checked = iTFFSettings.Instance.CoversApplyArtworkToEntireAlbum;
            coversApplyAlbumCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "CoversApplyArtworkToEntireAlbum");

            CoversSetPlayingTrack();
        }

        private void coversFromiTuneButton_Click(object sender, EventArgs e)
        {
            CoversSetPlayingTrack();
        }

        private void CoversSetPlayingTrack()
        {
            if (!iTunesActions.Instance.COMCallDisabled)
            {
                iTunesLib.IITTrack t = iTunesActions.Instance.PlayingTrack; // protegé
                if (t == null)
                    return;
                else if (coversApplyAlbumCheckBox.Checked)
                    coversSearchTextBox.Text = string.Format("{0} {1}", t.Artist, t.Album);
                else
                    coversSearchTextBox.Text = string.Format("{0} {1}", t.Artist, t.Name);
            }
        }

        private void coversSearchTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.Handled = true;
                CoversSearch();
            }
        }

        private void coversSearchButton_Click(object sender, EventArgs e)
        {
            CoversSearch();
        }

        private void CoversSearch()
        {
            coversSearchProgressBar.Style = ProgressBarStyle.Marquee;
            coversSearchProgressBar.Enabled = true;
            coversSearchProgressBar.Visible = true;
            coversSearchBackgroundWorker.RunWorkerAsync();
        }

        private void coversSearchBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = new AmazonWebService().GetAlbumCovers(coversSearchTextBox.Text);
        }

        private void coversSearchBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _covers = (List<AlbumCover>)e.Result;

            if (_covers == null)
                MessageBox.Show("Nothing was found. Try to change the keywords.", "Nothing found", MessageBoxButtons.OK, MessageBoxIcon.Information);
            else
                ShowCoversWithPaging();

            coversSearchProgressBar.Enabled = false;
            coversSearchProgressBar.Visible = false;

        }

        private void ShowCoversWithPaging()
        {

            // stocker le control avec previous et next
            Control prenext = coversFlowLayoutPanel.Controls[coversFlowLayoutPanel.Controls.Count - 1];
            coversFlowLayoutPanel.Controls.Clear();

            foreach (var cover in _covers.Skip(coversPerPage * _coversNumPage).Take(coversPerPage))
            {
                AlbumCoverUC uc = new AlbumCoverUC { Cover = cover };
                uc.Click += new EventHandler(uc_Click);

                coversFlowLayoutPanel.Controls.Add(uc);
            }

            coversPreviousButton.Enabled = true;
            coversNextButton.Enabled = true;

            if (_coversNumPage == 0)
                coversPreviousButton.Enabled = false;

            if ((_coversNumPage + 1) * coversPerPage >= _covers.Count)
                coversNextButton.Enabled = false;

            coversFlowLayoutPanel.Controls.Add(prenext);
        }

        void uc_Click(object sender, EventArgs e)
        {
            CoversApply(sender);
        }

        private void CoversApply(object sender)
        {
            if (!iTunesActions.Instance.COMCallDisabled)
            {
                coversSearchProgressBar.Value = 0;
                coversSearchProgressBar.Style = ProgressBarStyle.Continuous;
                coversSearchProgressBar.Enabled = true;
                coversSearchProgressBar.Visible = true;
                coversApplyBackgroundWorker.RunWorkerAsync(sender);
            }
        }

        private void coversApplyBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            AlbumCover cover = ((AlbumCoverUC)e.Argument).Cover;
            // sauver l'image dans un fichier temporaire
            string filename = Path.GetTempFileName();

            if (coversStoreMinimizedImageCheckBox.Checked)
                cover.ImageMedium.Save(filename);
            else
            {
                cover.FetchCovers(true);
                cover.ImageBig.Save(filename);
            }

            iTunesActions.Instance.SetImage(coversApplyBackgroundWorker, iTunesActions.Instance.PlayingTrack, filename, coversApplyAlbumCheckBox.Checked); // protégé
            e.Result = filename;

        }

        private void coversApplyBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            coversSearchProgressBar.Value = e.ProgressPercentage;
        }

        private void coversApplyBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                File.Delete((string)e.Result);
            }
            catch (Exception) { }

            coversSearchProgressBar.Enabled = false;
            coversSearchProgressBar.Visible = false;
            //MessageBox.Show("The covers has been successfully applied.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void coversPreviousButton_Click(object sender, EventArgs e)
        {
            _coversNumPage--;
            ShowCoversWithPaging();
        }

        private void coversNextButton_Click(object sender, EventArgs e)
        {
            _coversNumPage++;
            ShowCoversWithPaging();
        }

        #endregion

        #region Toaster
        private void InitializeToasterTab()
        {
            // toaster
            toasterEnableCheckBox.Checked = iTFFSettings.Instance.ToasterEnable;
            toasterEnableCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "ToasterEnable");

            toasterHideOnClickCheckBox.Checked = iTFFSettings.Instance.ToasterHideOnClick;
            toasterHideOnClickCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "ToasterHideOnClick");

            toasterReappearOnMouseOverCheckBox.Checked = iTFFSettings.Instance.ToasterReappearOnMouseHOver;
            toasterReappearOnMouseOverCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "ToasterReappearOnMouseHOver");

            toasterShowForNumericUpDown.Value = iTFFSettings.Instance.ToasterShowToasterTimer;
            toasterShowForNumericUpDown.DataBindings.Add("Value", iTFFSettings.Instance, "ToasterShowToasterTimer");

            if (iTFFSettings.Instance.ToasterEnable)
                CreateToastForm();
        }

        private void toasterShowButton_Click(object sender, EventArgs e)
        {
            if (!iTunesActions.Instance.COMCallDisabled)
            {
                ShowToast(iTunesActions.Instance.PlayingTrack, true); // protégé
            }
        }


        private void toasterEnableCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (toasterEnableCheckBox.Checked)
                CreateToastForm();
            else
                DestructToastForm();
        }

        private void CreateToastForm()
        {
            if (_toastForm == null)
            {
                _toastForm = new ToastForm();
                _toastForm.Hide();
            }
        }

        private void DestructToastForm()
        {
            if (_toastForm != null)
                _toastForm.Close();
        }

        /// <summary>
        /// Shows the toaster
        /// </summary>
        /// <param name="iITTrack"></param>
        public void ShowToast(iTunesLib.IITTrack iITTrack, bool force)
        {
            if ((!iTFFSettings.Instance.ToasterEnable && !force) || iITTrack == null)
                return;

            // au cas ou le toaster est désactiver mais qu'il clique le bouton ou le raccourci pour l'afficher
            if (_toastForm == null)
                CreateToastForm();

            _toastForm.TrackName = iITTrack.Name;
            _toastForm.Artist = iITTrack.Artist;
            _toastForm.Album = iITTrack.Album;
            _toastForm.TimeWait = iTFFSettings.Instance.ToasterShowToasterTimer;

            if (iITTrack.Artwork.Count > 0)
                _toastForm.Picture = GetArtworkAsImage(iITTrack);
            else
                _toastForm.Picture = null;

            _toastForm.ShowToast();

        }

        #endregion

        #region lastfm

        bool _lastfmPasswordChanged = false;
        private void InitializeLastFMTab()
        {
            _lastfm = new LastFMManager();
            _lastfm.Username = iTFFSettings.Instance.LastFMUsername;
            _lastfm.PasswordHash = iTFFSettings.Instance.LastFMPasswordHash;

            // DATABINDINGS
            lastfmEnableCheckBox.Checked = iTFFSettings.Instance.LastFMEnable;
            lastfmEnableCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "LastFMEnable");
            lastfmUsernameTextBox.Text = iTFFSettings.Instance.LastFMUsername;
            lastfmUsernameTextBox.DataBindings.Add("Text", iTFFSettings.Instance, "LastFMUsername");

            lastfmPasswordTextBox.Text = new String(' ', iTFFSettings.Instance.LastFMPasswordLength);

            LastFMUdpateStatistics();

            _lastfm.LastFMNotifiate += new LastFMManager.LastFMNotifiateEventHandler(_lastfm_LastFMNotifiate);
            _lastfm.TracksSubmitted += new LastFMManager.TracksSubmittedEventHandler(_lastfm_TracksSubmitted);

            LastFMTryHandshake();
        }

        void _lastfm_TracksSubmitted(object sender, TracksSubmittedEventArgs e)
        {
            if (InvokeRequired)
                this.Invoke(new LastFMManager.TracksSubmittedEventHandler(_lastfm_TracksSubmitted), sender, e);
            else
            {
                LastFMUdpateStatistics();
                if (e.SubmittedTracks != null)
                    lastfmStatLastSubmittedSongLabel.Text = string.Format("{0} - {1}", e.SubmittedTracks.Last().Artist, e.SubmittedTracks.Last().TrackName);
            }
        }

        void _lastfm_LastFMNotifiate(object sender, LastFMNotifiateEventArgs e)
        {
            if (InvokeRequired || lastfmStatLastServerResponseLabel.InvokeRequired || lastfmUsernameIncorrectLabel.InvokeRequired || lastfmStatLastServerResponseLabel.InvokeRequired)
                Invoke(new LastFMManager.LastFMNotifiateEventHandler(_lastfm_LastFMNotifiate), sender, e);
            else
            {
                if (e.Notification != "OK")
                    lastfmStatLastServerResponseLabel.ForeColor = Color.Red;
                else
                    lastfmStatLastServerResponseLabel.ForeColor = Color.Black;

                if (e.Notification == "BADAUTH")
                {
                    lastfmUsernameIncorrectLabel.Visible = true;
                    lastfmTimer.Enabled = false;
                }
                else
                {
                    lastfmUsernameIncorrectLabel.Visible = false;
                    lastfmTimer.Enabled = true;
                }

                lastfmStatLastServerResponseLabel.Text = e.Notification;
            }
        }

        private void LastFMUdpateStatistics()
        {
            lastfmStatSongsSubmittedLabel.Text = iTFFSettings.Instance.LastFMSongsSubmitted.ToString();

            int c;
            if (iTFFSettings.Instance.LastFMSongsQueuedForSubmission == null)
                c = 0;
            else
                c = iTFFSettings.Instance.LastFMSongsQueuedForSubmission.Count;
            lastfmStatSongsQueuedForSubmissionLabel.Text = c.ToString();
            //lastfmStatSubmissionAttemptsLabel.Text = iTFFSettings.Instance.LastFMSubmissionAttempts.ToString();
        }

        private void LastFMTryHandshake()
        {
            if (lastfmEnableCheckBox.Checked && !string.IsNullOrEmpty(lastfmPasswordTextBox.Text) && !string.IsNullOrEmpty(lastfmUsernameTextBox.Text))
            {
                if (!lastfmTimer.Enabled)
                    lastfmTimer.Enabled = true;
                if (!lastfmHandshakeBackgroundWorker.IsBusy)
                    lastfmHandshakeBackgroundWorker.RunWorkerAsync();
            }
        }

        private void lastfmHandshakeBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            _lastfm.HandShake();
        }

        private void LastFMBeginPlay(iTunesLib.IITTrack iITTrack)
        {
            if (lastfmEnableCheckBox.Checked)
            {
                if (!lastfmBeginPlayBackgroundWorker.IsBusy)
                    lastfmBeginPlayBackgroundWorker.RunWorkerAsync(iITTrack);
            }
        }

        private void lastfmBeginPlayBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            _lastfm.BeginPlay((iTunesLib.IITTrack)e.Argument);
        }

        private void lastfmPasswordTextBox_Enter(object sender, EventArgs e)
        {
            if (!_lastfmPasswordChanged)
            {
                lastfmPasswordTextBox.Text = null;
                _lastfmPasswordChanged = true;
            }
        }

        private void lastfmEnableCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (lastfmEnableCheckBox.Checked)
                LastFMTryHandshake();
        }

        private void lastfmUsernameTextBox_Leave(object sender, EventArgs e)
        {
            _lastfm.Username = lastfmUsernameTextBox.Text;
            LastFMTryHandshake();
        }

        private void lastfmPasswordTextBox_Leave(object sender, EventArgs e)
        {
            _lastfm.SetPassword(lastfmPasswordTextBox.Text);
            LastFMTryHandshake();
        }


        private void lastfmTimer_Tick(object sender, EventArgs e)
        {
            if (lastfmEnableCheckBox.Checked)
            {
                if (!_lastfm.HandShaked)
                    LastFMTryHandshake();

                // stocker la track en submission queue
                if (!iTunesActions.Instance.COMCallDisabled)
                {
                    if (!lastfmCheckTimeBackgroundWorker.IsBusy)
                        lastfmCheckTimeBackgroundWorker.RunWorkerAsync();
                }
            }
            // désactiver si nécessaire
            else
                lastfmTimer.Enabled = false;
        }


        private void lastfmCheckTimeBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            _lastfm.CheckTime(iTunesActions.Instance.PlayingTrack); // protégé
        }

        private void lastfmUsernameAndPasswordTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (lastfmPasswordTextBox == (object)sender)
                    _lastfm.SetPassword(lastfmPasswordTextBox.Text);

                LastFMTryHandshake();
            }
        }

        #endregion

        #region Lyrics
        private void InitializeLyricsTab()
        {
            _lyrics = new LyricsManager
            {
                SaveAuto = iTFFSettings.Instance.LyricsAutoDownload,
                SaveToFiles = iTFFSettings.Instance.LyricsStoreTextFiles,
                SaveToFilesPath = iTFFSettings.Instance.LyricsTextFilesPath,
                SaveToTags = iTFFSettings.Instance.LyricsStoreIntoTags,
                ExcludePodcasts = iTFFSettings.Instance.LyricsExcludePodcasts
            };

            // databindings
            lyricsAutoDownloadCheckBox.Checked = iTFFSettings.Instance.LyricsAutoDownload;
            lyricsAutoDownloadCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "LyricsAutoDownload", false, DataSourceUpdateMode.OnPropertyChanged);

            lyricsStoreIntoTagsCheckBox.Checked = iTFFSettings.Instance.LyricsStoreIntoTags;
            lyricsStoreIntoTagsCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "LyricsStoreIntoTags", false, DataSourceUpdateMode.OnPropertyChanged);

            lyricsStoreTextCheckBox.Checked = iTFFSettings.Instance.LyricsStoreTextFiles;
            lyricsStoreTextCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "LyricsStoreTextFiles", false, DataSourceUpdateMode.OnPropertyChanged);

            lyricsExcludePodcastsCheckBox.Checked = iTFFSettings.Instance.LyricsExcludePodcasts;
            lyricsExcludePodcastsCheckBox.DataBindings.Add("Checked", iTFFSettings.Instance, "LyricsExcludePodcasts", false, DataSourceUpdateMode.OnPropertyChanged);

            lyricsTextFilePathTextBox.Text = iTFFSettings.Instance.LyricsTextFilesPath;
            lyricsTextFilePathTextBox.DataBindings.Add("Text", iTFFSettings.Instance, "LyricsTextFilesPath");

            if (!Directory.Exists(iTFFSettings.Instance.LyricsTextFilesPath))
                lyricsTextFilePathTextBox.BackColor = Color.IndianRed;

            LyricsInitializeTests();

        }


        private void LyricsPlay(iTunesLib.IITTrack track)
        {
            if (_lyricsForm == null)
                _lyricsForm = new LyricsForm(this, _lyrics);
            _lyricsForm.PlayingTrack = track;

            if (lyricsAutoDownloadCheckBox.Checked && track != null)
                LyricsDownloadAndApply(track, false);
        }

        public void LyricsDownloadAndApply(iTunesLib.IITTrack track, bool force)
        {
            if (!iTunesActions.Instance.COMCallDisabled)
            {
                if (_lyricsForm == null)
                    _lyricsForm = new LyricsForm(this, _lyrics);
                _lyricsForm.PlayingTrack = iTunesActions.Instance.PlayingTrack; // protégé

                if (!lyricsSaveBackgroundWorker.IsBusy)
                {
                    _lyricsForm.AjaxLoadVisible = true;
                    lyricsSaveBackgroundWorker.RunWorkerAsync(new LyricsDownloadAndApplyArgs { Track = track, Force = force });
                }
            }
        }

        private void lyricsSaveBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            LyricsDownloadAndApplyArgs a = (LyricsDownloadAndApplyArgs) e.Argument;
            e.Result = _lyrics.DownloadAndSaveLyrics(a.Track, a.Force, null);
        }

        private void lyricsSaveBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            LyricsDesignation d = null;
            // si pas d'erreur, récupérer la valeur
            if (e.Error == null)
                d = (LyricsDesignation)e.Result;

            if (d != null)
                LyricsApplyValues(d);
            _lyricsForm.AjaxLoadVisible = false;
        }

        private void showLyricsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!iTunesActions.Instance.COMCallDisabled)
            {
                // get lyrics for playing song
                LyricsDownloadAndApply(iTunesActions.Instance.PlayingTrack, true);
                LyricsShow();
            }
        }

        public void LyricsApplyValues(LyricsDesignation d)
        {
            if (!iTunesActions.Instance.COMCallDisabled)
            {
                if (_lyricsForm == null)
                    _lyricsForm = new LyricsForm(this, _lyrics);

                _lyricsForm.PlayingTrack = iTunesActions.Instance.PlayingTrack;

                if (d == null)
                    _lyricsForm.GetLyrics(iTunesActions.Instance.PlayingTrack);
                else
                    _lyricsForm.SetLyrics(d, true);
            }
        }

        public void LyricsShow()
        {
            //_lyricsForm.Visible = true;
            _lyricsForm.Show();
            _lyricsForm.BringToFront();
            _lyricsForm.WindowState = FormWindowState.Normal;
        }

        private void lyricsAutoDownloadCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            _lyrics.SaveAuto = lyricsAutoDownloadCheckBox.Checked;
        }

        private void lyricsStoreIntoTagsCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            _lyrics.SaveToTags = lyricsStoreIntoTagsCheckBox.Checked;
        }

        private void lyricsStoreTextCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            _lyrics.SaveToFiles = lyricsStoreTextCheckBox.Checked;
        }

        private void lyricsExcludePodcastsCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            _lyrics.ExcludePodcasts = lyricsExcludePodcastsCheckBox.Checked;
        }

        private void lyricsTextFilePathTextBox_Validated(object sender, EventArgs e)
        {
            // vérifier que le dossier est correct, changer de couleur en conséquence
            if (Directory.Exists(lyricsTextFilePathTextBox.Text))
                lyricsTextFilePathTextBox.BackColor = Color.White;
            else
                lyricsTextFilePathTextBox.BackColor = Color.IndianRed;

            _lyrics.SaveToFilesPath = lyricsTextFilePathTextBox.Text;
        }

        private void lyricsTextFileBrowseButton_Click(object sender, EventArgs e)
        {
            if (lyricsFolderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                // appliquer le changement partout
                lyricsAutoDownloadCheckBox.Checked = true;
                lyricsTextFilePathTextBox.BackColor = Color.White;
                lyricsTextFilePathTextBox.Text = lyricsFolderBrowserDialog.SelectedPath;
                _lyrics.SaveToFilesPath = lyricsFolderBrowserDialog.SelectedPath;
                iTFFSettings.Instance.LyricsTextFilesPath = lyricsFolderBrowserDialog.SelectedPath;
            }
        }

        #region Download All
        private int _lyricsDownloadAllFound;
        private int _lyricsDownloadAllNotFound;

        private void lyricsDownloadAllButton_Click(object sender, EventArgs e)
        {
            if (!lyricsDownloadAllBackgroundWorker.IsBusy && !iTunesActions.Instance.COMCallDisabled)
            {
                _lyricsDownloadAllFound = 0;
                _lyricsDownloadAllNotFound = 0;

                lyricsDownloadAllProgressBar.Visible = true;
                lyricsDownloadAllProgressBar.Value = 0;
                lyricsDownloadAllFoundLabel.Text = null;
                lyricsDownloadAllFoundLabel.Visible = true;
                lyricsDownloadAllNotFoundLabel.Text = null;
                lyricsDownloadAllNotFoundLabel.Visible = true;

                lyricsDownloadAllButton.Text = "Cancel";

                lyricsDownloadAllStatusLabel.Visible = true;

                lyricsDownloadAllBackgroundWorker.RunWorkerAsync(lyricsNotFoundPlaylistCheckBox.Checked);
            }
            else
            {
                lyricsDownloadAllBackgroundWorker.CancelAsync();
                lyricsDownloadAllButton.Text = "Canceling... Please wait.";
            }
        }

        private void lyricsDownloadAllBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            bool createNoLyricsPlaylist = (bool)e.Argument;

            lyricsDownloadAllBackgroundWorker.ReportProgress(-1);

            List<iTunesLib.IITFileOrCDTrack> tracks = iTunesActions.Instance.GetSongsWithoutLyrics(_lyrics);
            if (tracks == null)
            {
                Utils.ShowErrorMessage("Don't disturb iTunes by opening preferences or track informations while processing searching lyrics.", "Can't perform lyrics search");
                return;
            }

            iTunesLib.IITUserPlaylist pl = null;
            if (createNoLyricsPlaylist)
            {
                pl = iTunesActions.Instance.CreatePlaylist("No Lyrics");
                iTunesActions.Instance.ClearPlaylist(pl);
            }
            int i = 1;
            foreach (var t in tracks)
            {
                if (lyricsDownloadAllBackgroundWorker.CancellationPending)
                    break;

                if (_lyrics.DownloadAndSaveLyrics(t, true, null) != null)
                    _lyricsDownloadAllFound++;
                else
                {
                    _lyricsDownloadAllNotFound++;
                    object tr = (object)t;
                    if (createNoLyricsPlaylist)
                        pl.AddTrack(ref tr);
                }

                lyricsDownloadAllBackgroundWorker.ReportProgress(i, tracks.Count);
                i++;
            }
        }

        private void lyricsDownloadAllBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage == -1)
                lyricsDownloadAllStatusLabel.Text = "Searching songs without lyrics...";
            else
            {
                lyricsDownloadAllStatusLabel.Text = string.Format("Searching lyrics... {0} of {1}", e.ProgressPercentage, (int)e.UserState);
                lyricsDownloadAllProgressBar.Value = (int) e.ProgressPercentage * 100 / (int)e.UserState;
                lyricsDownloadAllFoundLabel.Text = "Found: " + _lyricsDownloadAllFound.ToString();
                lyricsDownloadAllNotFoundLabel.Text = "Not found: " + _lyricsDownloadAllNotFound.ToString();
            }
        }

        private void lyricsDownloadAllBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lyricsDownloadAllStatusLabel.Text = "Finished!";
            lyricsDownloadAllButton.Text = "Try to download all missing lyrics (this may take a while)";
        }
        #endregion

        private void button3_Click(object sender, EventArgs e)
        {
            iTunesActions.Instance.DeleteAllLyrics(_lyrics);
        }

        List<iTunesLib.IITTrack> _lyricTracksTest;
        private void LyricsInitializeTests()
        {
            foreach (var p in _lyrics.Providers)
                lyricsDebugListBox.Items.Add(p);

            // initialiser le débug en chargeant les tracks
            _lyricTracksTest = new List<iTunesLib.IITTrack>();
            _lyricTracksTest.Add(iTunesActions.Instance.GetTrackFromTrackDatabaseID(36, 15163, 15395, 622)); // ben harper, sexual healing
            _lyricTracksTest.Add(iTunesActions.Instance.GetTrackFromTrackDatabaseID(36, 15163, 15179, 406)); // muse absolution
            _lyricTracksTest.Add(iTunesActions.Instance.GetTrackFromTrackDatabaseID(36, 15163, 16573, 1800)); // JJ feat matt costa lullaby
            _lyricTracksTest.Add(iTunesActions.Instance.GetTrackFromTrackDatabaseID(36, 15163, 15885, 1112)); // red hot i could have lied


            foreach (var track in _lyricTracksTest)
            {
                if (track != null)
                {
                    lyricsDebugTextBox.AppendText(string.Format("{0}: {1} - {2}\n", track.TrackDatabaseID, track.Artist, track.Name));
                }
            }
        }
        private void lyricsDebugButton_Click(object sender, EventArgs e)
        {
            //iTunesLib.IITTrack tr = iTunesActions.Instance.PlayingTrack;
            //int s, p, t, d;
            //tr.GetITObjectIDs(out s, out p, out t, out d);

            //return;
            LyricsProvider p = (LyricsProvider)lyricsDebugListBox.SelectedItem;

            foreach (var track in _lyricTracksTest)
            {
                LyricsDesignation d = _lyrics.DownloadAndSaveLyrics(track, true, p);

                if (d == null)
                    Log.Instance.WriteLine(string.Format("[Lyrics Tests] Nothing found for provider {0} track: {1} - {2}", p, track.Artist, track.Name));
                else
                {
                    Log.Instance.WriteLine(string.Format("[Lyrics Tests] Lyrics found for provider {0} track: {1} - {2}", p, track.Artist, track.Name));
                    Log.Instance.WriteLine(d.Lyrics);
                }

            }
        }

        #endregion

        #region MusicDNS

        private MusicDNSWaitForm _musicDNSWaitForm;
        public void MusicDNSSearchTagsForSelectedTrack()
        {
            MusicDNSInfos = null;
            // récupérer les chansons sélectionnées
            var tracks = iTunesActions.Instance.SelectedTracks;
            if (tracks == null)
                return;
            else
            {
                _musicDNSWaitForm = new MusicDNSWaitForm();
                _musicDNSWaitForm.Show();
                musicdnsBackgroundWorker.RunWorkerAsync(tracks);
            }
        }

        private void musicdnsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = MusicDNS.Instance.GetTagsForSongs(musicdnsBackgroundWorker, (iTunesLib.IITTrack[])e.Argument);
        }

        private void musicdnsBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            switch (e.ProgressPercentage)
            {
                case 0:
                    _musicDNSWaitForm.Label = "Analyse des fichiers audio et récupération des empreintes";
                    break;

                case 1:
                    _musicDNSWaitForm.Label = "Téléchargements des tags";
                    break;
            }
        }

        private void musicdnsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _musicDNSWaitForm.Close();

            MusicDNSInfos = (ITTrackInfos[])e.Result;
            if (MusicDNSInfos.Length != 0)
            {

                // vérifier chaque élément s'il a des conflits
                bool showForm = false;
                foreach (var infos in MusicDNSInfos)
                {
                    if (infos.MatchedTracks != null && infos.MatchedTracks.Count > 0)
                    {
                        if (infos.MatchedTracks.Count > 1)
                        {
                            showForm = true;
                            foreach (var mt in infos.MatchedTracks)
                            {
                                if (mt.Releases.Count == 1)
                                    mt.SelectedTrackRelease = mt.Releases[0];
                            }
                        }
                        else
                        {
                            if (infos.MatchedTracks[0].Releases.Count == 1)
                                infos.MatchedTracks[0].SelectedTrackRelease = infos.MatchedTracks[0].Releases[0];
                            else
                                showForm = true;
                            infos.SelectedMatchedTrack = infos.MatchedTracks[0];
                        }
                    }
                }

                if (showForm)
                {
                    ChooseMusicDNS form = new ChooseMusicDNS(this, MusicDNSInfos);
                    form.BringToFront();
                    form.ShowDialog();
                }
                else
                    MusicDNSApplyTags();


            }
        }

        public void MusicDNSApplyTags()
        {
            // parcourir tout et appliquer

            foreach (var infos in MusicDNSInfos)
            {
                if (infos.MatchedTracks != null && infos.MatchedTracks.Count > 0)
                {
                    infos.Track.Artist = infos.SelectedMatchedTrack.Artist.Name;
                    infos.Track.Name = infos.SelectedMatchedTrack.Title;
                    infos.Track.Album = infos.SelectedMatchedTrack.SelectedTrackRelease.Release.Title;
                    infos.Track.TrackNumber = infos.SelectedMatchedTrack.SelectedTrackRelease.TrackNumber;
                    infos.Track.TrackCount = infos.SelectedMatchedTrack.SelectedTrackRelease.Release.TrackCount;
                    if (infos.SelectedMatchedTrack.SelectedTrackRelease.Release.FirstRelease != null)
                        infos.Track.Year = infos.SelectedMatchedTrack.SelectedTrackRelease.Release.FirstRelease.Value.Year;
                }
            }
        }
        #endregion

        #region About
        public void InitializeAbout()
        {
            this.labelProductName.Text = AssemblyProduct;
            this.labelVersion.Text = String.Format("Version {0}", AssemblyVersion);
            this.labelCopyright.Text = AssemblyCopyright;
            this.labelCompanyName.Text = AssemblyCompany;
            this.textBoxDescription.Text = AssemblyDescription;
        }

        #region Assembly Attribute Accessors

        public string AssemblyTitle
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
                if (attributes.Length > 0)
                {
                    AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
                    if (titleAttribute.Title != "")
                    {
                        return titleAttribute.Title;
                    }
                }
                return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
            }
        }

        public string AssemblyVersion
        {
            get
            {
                return Assembly.GetExecutingAssembly().GetName().Version.ToString();
            }
        }

        public string AssemblyDescription
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
                if (attributes.Length == 0)
                {
                    return "";
                }
                return ((AssemblyDescriptionAttribute)attributes[0]).Description;
            }
        }

        public string AssemblyProduct
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
                if (attributes.Length == 0)
                {
                    return "";
                }
                return ((AssemblyProductAttribute)attributes[0]).Product;
            }
        }

        public string AssemblyCopyright
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
                if (attributes.Length == 0)
                {
                    return "";
                }
                return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
            }
        }

        public string AssemblyCompany
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
                if (attributes.Length == 0)
                {
                    return "";
                }
                return ((AssemblyCompanyAttribute)attributes[0]).Company;
            }
        }
        #endregion


        #endregion

        #region AddToPlaylist
        public void AddSelectedSongToPlaylist()
        {
            if (!iTunesActions.Instance.COMCallDisabled)
            {
                var track = iTunesActions.Instance.PlayingTrack; // protégé

                if (!string.IsNullOrEmpty(track.Artist))
                {
                    // search playlist
                    if (iTunesActions.Instance.GetPlaylists().Any(pl => pl.Name == track.Artist && pl.Kind == iTunesLib.ITPlaylistKind.ITPlaylistKindUser))
                    {
                        var playlist = (iTunesLib.IITUserPlaylist)iTunesActions.Instance.GetPlaylists().First(pl => pl.Name == track.Artist && pl.Kind == iTunesLib.ITPlaylistKind.ITPlaylistKindUser);
                        
                        // check if track isn't already in the playlist
                        bool exists = false;
                        foreach (iTunesLib.IITTrack tr in playlist.Tracks)
                        {
                            if (tr.TrackDatabaseID == track.TrackDatabaseID)
                                exists = true;
                        }

                        if (!exists)
                        {
                            var objectTrack = (object)track;
                            playlist.AddTrack(ref objectTrack);
                        }
                    }
                    else
                    {
                        // create playlist
                        var playlist = iTunesActions.Instance.CreatePlaylist(track.Artist);
                        var objectTrack = (object)track;
                        playlist.AddTrack(ref objectTrack);
                    }

                    // show toast to confirm the aciton went well
                    ShowToast(iTunesActions.Instance.PlayingTrack, true);
                }

            }
        }

        #endregion
    }
}
